import numpy as np

class Lost:
    def __init__(self) -> None:
        pass
    def __call__(self,y_hat:np.matrix,y:np.matrix) -> float:
        return 0
    def Dl_dyhat(self,y_hat:np.matrix,y:np.matrix) -> np.matrix:
        return 0
    def Id() -> int:
        return 0
    
class BinaryCrossentropy(Lost):
    def __init__(self) -> None:
        super().__init__()
        
    def __call__(self,y_hat:np.matrix,y:np.matrix) -> float:
        """"
        计算损失
        """     
        return - y*np.log(y_hat) - (1-y)*np.log(1-y_hat)
        
        
    def Dl_dyhat(self,y_hat:np.matrix,y:np.matrix) -> np.matrix:
        return - y/y_hat + (1-y)/(1-y_hat)
    def Id() -> int:
        return 1

class Crossentropy(Lost):
    def __init__(self) -> None:
        super().__init__()
        
    def __call__(self,y_hat:np.matrix,y:np.matrix) -> float:
        """"
        计算损失
        """     
        res = - y*np.log(y_hat)
        return res
        
    def Dl_dyhat(self,y_hat:np.matrix,y:np.matrix) -> np.matrix:
        return - y/y_hat
    
    def Id() -> int:
        return 2